package run.bottle.securityauth.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import run.bottle.common.context.ThreadContext;
import run.bottle.common.entity.AppUser;
import run.bottle.common.entity.mvc.RestResponse;
import run.bottle.common.exception.ServiceException;
import run.bottle.common.exception.UnsupportedException;
import run.bottle.urp.service.UserService;

import java.util.Base64;
import java.util.Map;

/**
 * @author liyc
 * @date 2022-04-10
 */
@RestController
@RequestMapping("/public/auth")
public class LoginController {

    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Value("${security.oauth2.client.client-id:bottle-client}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret:bottle-secret}")
    private String clientSecret;

    @Value("${security.oauth2.client.access-token-uri}")
    private String ticketsUrl;

    private final RestTemplate restTemplate;
    private final UserService userService;

    public LoginController(RestTemplate restTemplate, UserService userService) {
        this.restTemplate = restTemplate;
        this.userService = userService;
    }

    @PostMapping("/login")
    public RestResponse login(@RequestBody Map<String, Object> authBody) {

        logger.info("用户名{} 密码{}", authBody.get("username"), authBody.get("password"));

        String encodedCredentials = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes());

        HttpHeaders headers = new HttpHeaders();
        headers.add("x-client-id", clientId);
        headers.add("Authorization", "Basic " + encodedCredentials);
        headers.set(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded;charset=UTF-8");

        String params = "grant_type=password&username=" + authBody.get("username") + "&password=" + authBody.get("password");
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity(params, headers);

        Map<String, Object> map;
        try {
            map = restTemplate.exchange(ticketsUrl, HttpMethod.POST, entity, Map.class).getBody();
        } catch (HttpClientErrorException e) {
            if (HttpStatus.UNAUTHORIZED.equals(e.getStatusCode())) {
                throw new UnsupportedException(e.getMessage(), e);
            }
            throw new ServiceException(e.getMessage(), e);
        }

        final AppUser currentUser;
        if (map.get("access_token") != null) {
            currentUser = userService.getAppUserByUsername((String) authBody.get("username"));
            if (currentUser.getStatus() != null && !currentUser.getStatus()) {
                logger.warn("用户{}已被禁用!", authBody.get("username"));
                currentUser.setMessage("用户"+ authBody.get("username") +"已被禁用!");
                currentUser.setAuthResult(false);
            } else {
                ThreadContext.setAccessToken((String) map.get("access_token"));
                currentUser.setToken((String) map.get("access_token"));
                currentUser.setAuthResult(true);
            }
        } else {
            currentUser = new AppUser();
            currentUser.setAuthResult(false);
            logger.warn("用户名或密码错误!");
        }
        return RestResponse.ok().result(currentUser);
    }

    @PostMapping("/logout")
    public RestResponse logout(@RequestBody Map<String, String> logoutParam) {
        String token = logoutParam.get("token");
        // TODO 撤销令牌
        return RestResponse.ok().message("注销成功");
    }

}
